package com.aoip.telemetry.telemetry.quartz.task.datamerge;

import com.aoip.telemetry.telemetry.core.redis.RedisCache;
import com.aoip.telemetry.telemetry.entity.common.QuerySourceDataEntity;
import com.aoip.telemetry.telemetry.entity.common.TableDataEntity;
import com.aoip.telemetry.telemetry.entity.enums.CacheKeyEnum;
import com.aoip.telemetry.telemetry.entity.merge.DataMergeRuleDetailEntity;
import com.aoip.telemetry.telemetry.entity.merge.DataMergeRuleGroupEntity;
import com.aoip.telemetry.telemetry.quartz.task.datamerge.mapper.DataMergeTaskMapper;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author chenbai
 * @version 1.0
 * @date 2022/10/13 22:08
 */
@Component
public class DataMergeTask {

    private static DataMergeTask dataMergeTask;

    @Resource
    private RedisCache redisCache;
    @Resource
    private DataMergeTaskMapper mapper;

    @PostConstruct
    public void init() {
        dataMergeTask = this;
    }

    public void dataMerge() {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime lastSync = now.minusMinutes(30);
        Collection<String> keys = dataMergeTask.redisCache.keys(CacheKeyEnum.DATA_MERGE_RULE_GROUP + ":*");
        for (String key : keys) {
            DataMergeRuleGroupEntity dataMergeRuleGroupEntity = dataMergeTask.redisCache.getCacheObject(key);
            String targetTable = dataMergeRuleGroupEntity.getRuleGroupTargetTable();
            String id = dataMergeRuleGroupEntity.getId();
            String targetField = dataMergeRuleGroupEntity.getRuleGroupTargetField();
            String targetTmField = dataMergeRuleGroupEntity.getRuleGroupTargetTmField();
            String[] split = targetField.split(",");
            int fieldNum = split.length;
            if (fieldNum < 1) {
                return;
            }
            Map<String, Map<String, Object>> allDataMap = new HashMap<>();
            List<DataMergeRuleDetailEntity> ruleDetailList = dataMergeTask.redisCache.getCacheList(CacheKeyEnum.DATA_MERGE_RULE_DETAIL + ":" + id);
            for (DataMergeRuleDetailEntity detailEntity : ruleDetailList) {
                String ruleSourceTable = detailEntity.getRuleSourceTable();
                String ruleSourceField = detailEntity.getRuleSourceField();
                String ruleTargetField = detailEntity.getRuleTargetField();
                String limitTimeField = detailEntity.getLimitTimeField();
                QuerySourceDataEntity entity = new QuerySourceDataEntity();
                entity.setTableName(ruleSourceTable);
                Map<String, Object> limitFieldsMap = new HashMap<>();
                limitFieldsMap.put(limitTimeField, lastSync);
                entity.setLimitFieldsMap(limitFieldsMap);
                entity.setQueryFields("stcd," + ruleSourceField + "," + limitTimeField);
                entity.setNow(now);
                List<Map<String, Object>> dataByTable = mapper.getDataByTable(entity);
                for (Map item : dataByTable) {
                    Object stcd = item.get("stcd");
                    Object data = item.get(ruleSourceField);
                    Object limitTime = item.get(limitTimeField);
                    String stKey = stcd + "," + limitTime;
                    Map<String, Object> map = allDataMap.get(stKey);
                    if (map == null) {
                        map = new HashMap<>(fieldNum);
                        allDataMap.put(stKey, map);
                    }
                    map.put(ruleTargetField, data);
                }
            }
            List<TableDataEntity> saveList = new ArrayList<>();
            for (Map.Entry<String, Map<String, Object>> next : allDataMap.entrySet()) {
                String stKey = next.getKey();
                Map<String, Object> value = next.getValue();
                if (value.size() == fieldNum) {
                    String[] stTime = stKey.split(",");
                    String stCode = stTime[0];
                    String tm = stTime[1];
                    value.put(targetTmField, tm);
                    TableDataEntity tableDataEntity = new TableDataEntity();
                    tableDataEntity.setTableName(targetTable);
                    tableDataEntity.setStCode(stCode);
                    tableDataEntity.setFieldMap(value);
                    tableDataEntity.setTm(tm);
                    saveList.add(tableDataEntity);
                }
            }
            for (TableDataEntity entity : saveList) {
                try {
                    String hasMergeKey = entity.getTableName() + entity.getStCode() + entity.getTm();
                    if (redisCache.hasKey(CacheKeyEnum.HAS_MERGE_DATA + ":" + hasMergeKey)) {
                        continue;
                    }
                    mapper.mysqlSaveSingle(entity);
                    redisCache.setCacheObject(CacheKeyEnum.HAS_MERGE_DATA + ":" + hasMergeKey, hasMergeKey, 12, TimeUnit.HOURS);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }
    }


}
